package com.yiguantong.police.webview;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.MainApplication;
import com.alibaba.fastjson.JSONObject;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.yiguantong.police.R;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.yiguantong.police.BaseActivity;
import com.yiguantong.police.ui.utils.MyLog;

import java.net.MalformedURLException;
import java.net.URL;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class WebViewActivity extends BaseActivity {
    private WebView webView;
    private ProgressBar progress;
    private LinearLayout loading;
    private JavaScriptObject javascriptObject;

    private String title;

    //URL
    private String url;
    //webSetting
    private WebSettings webSettings;

    //高德定位
    public static AMapLocationClient locationClient = null;
    private static AMapLocationClientOption locationOption = null;
    //定位结果
    public static String locationResult = "";

    //webView中二维码扫描核销功能
    public static final int RequestCodeTwoDimensionCodeFromWebView = 209;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview_activity_layout);
        requestPermission(this);
        initView();
        //每个界面的传值到webview的接收逻辑
        if (null != getIntent()) {
            Bundle bundle = this.getIntent().getExtras();
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            if (null != bundle) {
                initIntent(bundle);
            }
        }
        initWebParams();
    }

    //设备API大于6.0时，主动申请权限
    private void requestPermission(Activity context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE}, 0);

            }
        }
    }

    @SuppressLint("JavascriptInterface")
    private void initView() {
        webView = findViewById(R.id.webview);
        loading = findViewById(R.id.loading_tv);
        progress = findViewById(R.id.progress);
        javascriptObject = new JavaScriptObject(this);
        webView.addJavascriptInterface(javascriptObject, "javascriptObject");

    }

    /**
     * 传值处理方法
     * 1.widget:指在HoneFragment的通知栏常驻跳转
     * 2.start_page:指在Welcome(启动页)的跳转
     * 3.else:指在正常情况下的跳转
     */
    private void initIntent(Bundle bundle) {
        Intent intent = getIntent();
        if (intent == null)
            return;
        url = bundle.getString("url");
        if (intent.hasExtra("title")) {
            title = intent.getStringExtra("title");

        }
    }

    @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"})
    private void initWebParams() {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
        }
        if (!TextUtils.isEmpty(url)) {
            loading.setVisibility(View.VISIBLE);
            loadUrl(url);
        }

        webSettings = webView.getSettings();
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        webView.setInitialScale(25);
        webView.getSettings().setUseWideViewPort(true);


        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        //webSettings.setAllowFileAccess(true);
        webSettings.setSavePassword(false);
        // 修补WebView域控制不严格漏洞
        webSettings.setAllowFileAccess(false);
        webSettings.setAllowFileAccessFromFileURLs(false);
        webSettings.setAllowUniversalAccessFromFileURLs(false);

        webSettings.setSaveFormData(true);
        webSettings.setLoadsImagesAutomatically(true);
        webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        webSettings.setDefaultFontSize(18);
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
//        webSettings.setBlockNetworkImage(false);
        //VIVO Y35等低端机型第三方页面如果样式不标准可能出现样式问题
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }
        if (Build.VERSION.SDK_INT >= 21) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        setParam();
        if (Build.VERSION.SDK_INT >= 19) {
            // webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        }
        webSettings.setJavaScriptEnabled(true);
        webView.requestFocus();
        webView.setWebChromeClient(new WebChromeClient());
        webView.setWebViewClient(new WebViewClient());
        webSettings.setLoadsImagesAutomatically(true); //自动加载图片
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                //显示进度条
                progress.setProgress(newProgress);
                if (newProgress == 100) {
                    MyLog.i("加载完成1。。。。。");
                    loading.setVisibility(View.GONE);
                    //加载完毕隐藏进度条
                    progress.setVisibility(View.GONE);
                } else {
                    loading.setVisibility(View.VISIBLE);
                }
                super.onProgressChanged(view, newProgress);
            }
        });
//        webView.setWebViewClient(new WebViewClient() {
//            @Override
//            public void onPageFinished(WebView view, String url)
//            {
//                super.onPageFinished(view, url);
//                MyLog.i("加载完成3。。。。。");
//                // 加载完成
//            }
//        });
    }

    private void loadUrl(String url) {
        try {
            new URL(url);
        } catch (MalformedURLException e) {
            finish();
            return;
        }
        webView.loadUrl(url);
    }

    private void setParam() {

        String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
        webSettings.setUserAgentString(new WebView(this).getSettings().getUserAgentString());
        if (android.os.Build.VERSION.SDK_INT >= 11) {
            webSettings.setDisplayZoomControls(false);
        }
        //启用地理定位
        webSettings.setGeolocationEnabled(true);
        //设置定位的数据库路径
        webSettings.setGeolocationDatabasePath(dir);

        // 设置支持JavaScript
        webSettings.setAppCacheEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setMediaPlaybackRequiresUserGesture(false);
        // 设置定位的数据库路径
        // 最重要的方法，一定要设置，这就是出不来的主要原因

        // 把本类的一个实例添加到js的全局对象window中，
        // 移除高危JS接口
        webView.removeJavascriptInterface("searchBoxJavaBridge_");
        webView.removeJavascriptInterface("accessibility");
        webView.removeJavascriptInterface("accessibilityTraversal");

        webView.setFocusable(true);
        webView.setFocusableInTouchMode(true);
        webView.requestFocusFromTouch();
        webView.clearCache(true);
    }


    private class JavaScriptObject {
        private Context context;
        public String locationHook = null;

        public JavaScriptObject(Context context) {
            this.context = context;
        }

        //异步获取定位信息
        @JavascriptInterface
        public void getLocation(final String key) {
            if (key == null || key.equals("")) {
                WebViewActivity.this.toast("未提供回调方法");
                return;
            }
            locationHook = key;
            location();
        }

        @JavascriptInterface
        public void normalTdcodeIgnoreLogin(final String hookKey) {
            RxPermissions.getInstance(context).request(Manifest.permission.CAMERA)
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean granted) throws Exception {
                            if (granted) {
                                try {
                                    final Intent intent = new Intent(WebViewActivity.this, com.yiguantong.police.qrCode.ui.CaptureActivity.class);
                                    intent.putExtra("fromWebView", true);
                                    intent.putExtra("simpleScanner", true);
                                    RxActivityResult.startActivityForResult(WebViewActivity.this, intent, RequestCodeTwoDimensionCodeFromWebView)
                                            .subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
                                            .subscribe(new Observer<ActivityResult>() {
                                                Disposable d;

                                                @Override
                                                public void onSubscribe(Disposable d) {
                                                    this.d = d;
                                                }

                                                @Override
                                                public void onNext(final ActivityResult activityResult) {
                                                    if (activityResult.getRequestCode() != RequestCodeTwoDimensionCodeFromWebView)
                                                        return;
                                                    if (!d.isDisposed()) {
                                                        d.dispose();
                                                    }
                                                    if (activityResult != null && activityResult.isOk()) {
                                                        final Intent intent1 = activityResult.getData();
                                                        if (intent1 != null && !TextUtils.isEmpty(intent1.getStringExtra("sResult"))) {
                                                            runOnUiThread(new Runnable() {
                                                                @Override
                                                                public void run() {
                                                                    JSONObject jsonObject = new JSONObject();
                                                                    jsonObject.put("errorCode", 1);
                                                                    jsonObject.put("resultInfo", intent1.getStringExtra("sResult"));
                                                                    jsCallback(hookKey, jsonObject.toJSONString());
                                                                }
                                                            });
                                                        }
                                                    }
                                                }

                                                @Override
                                                public void onError(Throwable e) {
                                                    JSONObject jsonObject = new JSONObject();
                                                    jsonObject.put("errorCode", 0);
                                                    jsonObject.put("errorInfo", e.toString());
                                                    jsCallback(hookKey, jsonObject.toJSONString());
                                                }

                                                @Override
                                                public void onComplete() {

                                                }
                                            });
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            } else {
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put("errorCode", 0);
                                jsonObject.put("errorInfo", "授权失败");
                                jsCallback(hookKey, jsonObject.toJSONString());
                                //拒绝后弹出的弹窗
                                showPermissionDialog(
                                        getResources().getString(R.string.camera_permission) + getResources().getString(R.string.permission),
                                        getResources().getString(R.string.dialog_cancle_text),
                                        getResources().getString(R.string.dialog_open_text), "");
                                return;
                            }
                        }
                    });
        }

        //异步获取定位信息
        @JavascriptInterface
        public void exportData(final String url) {
            try {
                openBrowser(context, url);
//                downLoad("http://192.168.3.142:8989/healthInfo/exportExcel?groupId=1&startDate=20200215&endDate=20200216", "123.xls");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        static final int REQUEST_IMAGE_CAPTURE = 1;

        //拍照
        @JavascriptInterface
        public void appHandleCamera(final String hookKey) {
            RxPermissions.getInstance(context).request(Manifest.permission.CAMERA)
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean granted) throws Exception {
                            if (granted) {
                                try {
                                    final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                                        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            } else {
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put("errorCode", 0);
                                jsonObject.put("errorInfo", "授权失败");
                                jsCallback(hookKey, jsonObject.toJSONString());
                                //拒绝后弹出的弹窗
                                showPermissionDialog(
                                        getResources().getString(R.string.camera_permission) + getResources().getString(R.string.permission),
                                        getResources().getString(R.string.dialog_cancle_text),
                                        getResources().getString(R.string.dialog_open_text), "");
                                return;
                            }
                        }
                    });
        }
    }

    private void location() {
        RxPermissions.getInstance(WebViewActivity.this).request(Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            if (locationClient == null) {
                                locationClient = new AMapLocationClient(MainApplication.getIns());
                            }
                            if (locationOption == null) {
                                //初始化定位参数
                                locationOption = new AMapLocationClientOption();
                                //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
                                locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
                                locationOption.setOnceLocation(true);//可选，设置是否单次定位。默认是false
                                locationOption.setLocationCacheEnable(false);//关闭缓存机制
                            }
                            locationClient.setLocationListener(new AMapLocationListener() {
                                @Override
                                public void onLocationChanged(AMapLocation amapLocation) {
                                    if (amapLocation == null)
                                        return;
                                    MyLog.i("定位返回信息：" + amapLocation);
                                    com.alibaba.fastjson.JSONObject object = new com.alibaba.fastjson.JSONObject();
                                    if (amapLocation.getErrorCode() == 0) {
                                        //解析amapLocation获取相应内容。
                                        String longitude = amapLocation.getLongitude() + "";
                                        String latitude = amapLocation.getLatitude() + "";
                                        String province = amapLocation.getProvince();
                                        String city = amapLocation.getCity();
                                        String location = amapLocation.getCity();
                                        if (!TextUtils.isEmpty(location)) {
                                            location = location.replace("市", "");
                                        }
                                        String district = amapLocation.getDistrict();
                                        String adCode = amapLocation.getAdCode();
                                        MyLog.i("定位" + "经纬度：" + longitude + "," + latitude + "地理位置：" + province + "-" + city + "-" + district +
                                                "城市编码：" + adCode);
                                        com.alibaba.fastjson.JSONObject locationObj = new com.alibaba.fastjson.JSONObject();
                                        locationObj.put("longitude", longitude);
                                        locationObj.put("latitude", latitude);
                                        locationObj.put("country", amapLocation.getCountry());
                                        locationObj.put("province", province);
                                        locationObj.put("city", city);
                                        locationObj.put("cityCode", amapLocation.getCityCode());
                                        locationObj.put("district", amapLocation.getDistrict());
                                        locationObj.put("adCode", amapLocation.getAdCode());
                                        locationObj.put("address", amapLocation.getAddress());
                                        object.put("location", locationObj);
                                        object.put("errorCode", 1);
                                        object.put("errorInfo", "");
                                    } else {
                                        //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                                        MyLog.i("AmapError", "location Error, ErrCode:" + amapLocation.getErrorCode() + ", errInfo:" + amapLocation.getErrorInfo());
                                        object.put("errorCode", 0);
                                        object.put("errorInfo", amapLocation.getErrorInfo());
                                    }
                                    locationResult = object.toJSONString();
                                    if (!TextUtils.isEmpty(javascriptObject.locationHook)) {
                                        WebViewActivity.this.jsCallback(javascriptObject.locationHook, locationResult);
                                        javascriptObject.locationHook = null;
                                    }
                                    locationClient.stopLocation();//停止定位后，本地定位服务并不会被销毁
                                }
                            });
                            locationClient.startLocation();
                        } else {
                            com.alibaba.fastjson.JSONObject object = new com.alibaba.fastjson.JSONObject();
                            object.put("errorCode", 0);
                            object.put("errorInfo", "授权失败");
                            if (!TextUtils.isEmpty(javascriptObject.locationHook)) {
                                WebViewActivity.this.jsCallback(javascriptObject.locationHook, object.toJSONString());
                                javascriptObject.locationHook = null;
                            }
                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                    }
                });

    }

    /**
     * 调用第三方浏览器打开
     *
     * @param context
     * @param url     要浏览的资源地址
     */
    public static void openBrowser(Context context, String url) {
        final Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.parse(url));
// 注意此处的判断intent.resolveActivity()可以返回显示该Intent的Activity对应的组件名
// 官方解释 : Name of the component implementing an activity that can display the intent
        if (intent.resolveActivity(context.getPackageManager()) != null) {
            final ComponentName componentName = intent.resolveActivity(context.getPackageManager()); // 打印Log   ComponentName到底是什么 L.d("componentName = " + componentName.getClassName());
            context.startActivity(Intent.createChooser(intent, "请选择浏览器"));
        } else {
            Toast.makeText(context.getApplicationContext(), "请下载浏览器", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onMenuClick(MenuItem menuItem) {
        super.onMenuClick(menuItem);
        switch (menuItem.getItemId()) {
            case R.id.refresh:
                if (webView != null) {
                    webView.reload();
                }
                break;
            default:
                break;
        }
    }

    /**
     * 原生回调js方法
     *
     * @param hookKey
     * @param json
     */
    public void jsCallback(final String hookKey, final String json) {
        if (webView == null || TextUtils.isEmpty(hookKey))
            return;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                webView.loadUrl("javascript:appCallback('" + hookKey + "','" + json + "')");
            }
        });
    }
}
